/*
 * Copyright (C) 2009 M. Hautle.
 * 
 * This file is part of TrackedBean.
 * 
 * TrackedBean is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any later version.
 * 
 * TrackedBean is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with TrackedBean. If not, see <http://www.gnu.org/licenses/>.
 */
package ch.trackedbean.util;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.*;

/**
 * Helper for reading configurations.
 * 
 * @author M. Hautle
 */
public class ConfigurationHelper {
	/** The general loger. */
	private static final Logger LOG = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);

	/** The base directory for the settings. */
	public static String BASE_LOCATION = "/META-INF/services/";

	/**
	 * Loads the configuration as {@link Properties} object.
	 * 
	 * @param name The name of the settings file (without suffix)
	 * @return The configuration or null
	 */
	public static Properties loadSettings(String name) {
		final URL url = ConfigurationHelper.class.getResource(BASE_LOCATION + name + ".properties");
		if (url == null)
			return null;
		try {
			return loadSettings(url.openStream());
		} catch (IOException e) {
			LOG.log(Level.WARNING, "Error while loading " + name, e);
			return null;
		}
	}

	/**
	 * Loads the configuration as {@link Properties} object.
	 * 
	 * @param in The inputstream of the settings file
	 * @return The configuration or null
	 * @throws IOException If something went wrong
	 */
	public static Properties loadSettings(InputStream in) throws IOException {
		try {
			final Properties p = new Properties();
			p.load(in);
			return p;
		} finally {
			if (in != null)
				in.close();
		}
	}

	/**
	 * Instanciates a object of the type specified by a property.
	 * 
	 * @param <T> The type of the object
	 * @param cfg The properties object representing the configuration
	 * @param property The name of the property in the configuration
	 * @return The instanciated object or null
	 */
	@SuppressWarnings("unchecked")
	public static <T> T create(Properties cfg, String property) {
		final String prop = cfg.getProperty(property);
		if (prop == null)
			return null;
		try {
			return (T) Class.forName(prop.trim()).newInstance();
		} catch (Exception e) {
			LOG.log(Level.WARNING, "Error while instanciating " + prop, e);
		}
		return null;
	}

	/**
	 * Returns the corresponding class object specified by a property.
	 * 
	 * @param <T> The class type
	 * @param cfg The properties object representing the configuration
	 * @param property The name of the property in the configuration
	 * @return The corresponding class or null
	 */
	@SuppressWarnings("unchecked")
	public static <T> Class<T> getClass(Properties cfg, String property) {
		final String prop = cfg.getProperty(property);
		if (prop == null)
			return null;
		try {
			return (Class<T>) Class.forName(prop.trim());
		} catch (Exception e) {
			LOG.log(Level.WARNING, "Error while looking up class " + prop, e);
		}
		return null;
	}

	/**
	 * Returns the entries of a list property.
	 * 
	 * @param cfg The properties object representing the configuration
	 * @param property The name of the property in the configuration
	 * @return The content of the property splitted by ',' or an empty array
	 */
	public static String[] getListEntries(Properties cfg, String property) {
		final String prop = cfg.getProperty(property);
		return prop != null ? prop.split("\\s*,") : new String[0];
	}
}
